/*
 * Copyright 2014 Semidata. All rights reserved.
 */
package com.semidata.trp.report.data;

import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

/**
 * @author shewei@semidata.com, She Wei
 * 
 */
public class UserData {

	private String userId;
	private Map<Integer, Map<Integer, UserReport>> dataMap;

	public UserData() {
		this.userId = null;
		this.dataMap = new TreeMap<>();
	}

	public UserData(String userId) {
		this.userId = userId;
		this.dataMap = new TreeMap<>();
	}

	public void load(String data) {

		int pos = data.indexOf('\t');
		if (pos == -1)
			throw new RuntimeException("can not parse user log: " + data);

		this.userId = data.substring(0, pos);
		pos++;

		while (true) {

			int[] nums = new int[5];
			for (int i = 0; i < 5; i++) {
				nums[i] = 0;
				while (true) {
					if (pos >= data.length())
						throw new RuntimeException("can not parse user log");
					char ch = data.charAt(pos);

					if (ch >= '0' && ch <= '9') {
						nums[i] = nums[i] * 10 + (ch - '0');
						pos++;
					} else {
						break;
					}
				}
				if (pos >= data.length())
					throw new RuntimeException("can not parse user log");
				char ch = data.charAt(pos);

				pos++;
				if (i < 4) {
					if (ch != ':')
						throw new RuntimeException("can not parse user log");

				} else {
					if (ch != ';')
						throw new RuntimeException("can not parse user log");
					UserReport report = new UserReport();
					report.setImpression(nums[2]);
					report.setClick(nums[3]);
					report.setCost(nums[4]);

					int resourceId = nums[0];
					int strategyId = nums[1];

					Map<Integer, UserReport> map = dataMap.get(resourceId);

					if (map == null) {
						map = new TreeMap<>();
						dataMap.put(resourceId, map);
					}
					map.put(strategyId, report);
				}
			}

			if (pos == data.length())
				break;
		}

	}

	public String toString() {

		StringBuffer sb = new StringBuffer();

		sb.append(userId);
		sb.append('\t');

		for (Map.Entry<Integer, Map<Integer, UserReport>> resource : dataMap
		        .entrySet()) {

			int resourceId = resource.getKey();
			Map<Integer, UserReport> map = resource.getValue();

			for (Map.Entry<Integer, UserReport> entry : map.entrySet()) {
				sb.append(resourceId);
				sb.append(':');
				sb.append(entry.getKey());
				sb.append(':');
				sb.append(entry.getValue().getImpression());
				sb.append(':');
				sb.append(entry.getValue().getClick());
				sb.append(':');
				sb.append(entry.getValue().getCost());
				sb.append(';');
			}
		}

		return sb.toString();
	}

	public String getUserId() {
		return userId;
	}

	public void setUserId(String userId) {
		this.userId = userId;
	}

	public Map<Integer, Map<Integer, UserReport>> getDataMap() {
		return dataMap;
	}

	public void add(int resourceId, int strategyId, int imp, int click,
	        int cost) {

		UserReport report = new UserReport(imp, click, cost);

		Map<Integer, UserReport> map = dataMap.get(resourceId);
		if (map == null) {
			map = new TreeMap<Integer, UserReport>();
			map.put(strategyId, report);
			dataMap.put(resourceId, map);
		} else {
			UserReport r = map.get(strategyId);
			if (r == null) {
				map.put(strategyId, report);
			} else {
				r.merge(report);
			}
		}

	}
	
	 public void merge(UserData userData) {
		 
		 for (Entry<Integer, Map<Integer, UserReport>> entry : userData.dataMap.entrySet()) {
			 int resourceId = entry.getKey();
			 Map<Integer, UserReport> map = dataMap.get(resourceId);
			 if (map == null) {
				 dataMap.put(entry.getKey(), entry.getValue());
			 } else {
				 merge(map, entry.getValue());
			 }
		 }
	 
	 
	 }

    private void merge(Map<Integer, UserReport> map,
            Map<Integer, UserReport> map2) {
    	
    	for (Entry<Integer, UserReport> entry : map2.entrySet()) {
    		
    		UserReport report = map.get(entry.getKey());
    		if (report == null) {
    			map.put(entry.getKey(), entry.getValue());
    		} else {
    			report.merge(entry.getValue());
    		}
    		
    	}
    	
    }

	public static void main(String[] args) {

		UserData data = new UserData("123456789012");

		data.add(1, 1, 1, 2, 3);
		data.add(1, 2, 11, 12, 13);
		data.add(1, 3, 21, 22, 23);
		data.add(1, 4, 31, 32, 33);
		data.add(1, 5, 41, 42, 43);
		data.add(2, 1, 91, 92, 93);
		data.add(2, 2, 911, 912, 913);
		data.add(2, 3, 921, 922, 923);
		data.add(2, 4, 931, 932, 933);

		String str = data.toString();
		System.out.println(str);

		data = new UserData();
		data.load(str);
		str = data.toString();
		System.out.println(str);

	}

	
   
}
